#include "inmersiongrafico.h"

InmersionGrafico::InmersionGrafico( QWidget* parent, DataStore* datastore )
: QFrame( parent ), _inmersion( NULL ), _datastore( datastore ), _buceador( NULL )
{
    setObjectName( "inmersionGrafico" );

    _borderwidth = 1; // border around draw area
    _topmarginpct = 10; // percentage of the graph above the superficie line
    _bottommarginpct = 10; // percentage of the graph below the profundidad maxima line
    _textmargin = 5; // space between the left of the grapharea and the text
    _marcadorsize = 6; // diameter of the marcador circle

    // margins between the area of the graph and the frame's border
    _drawareatopmargin = 75;
    _drawareabottommargin = 35;
    _drawareasidemargin = 50;

    _drawareabrush.setStyle( Qt::SolidPattern );

    _linepen.setStyle( Qt::SolidLine );
    _linepen.setWidth(2);

    QColor gridlinecolor( "#555555" );
    gridlinecolor.setAlpha( 50 );
    _gridlinepen.setColor( gridlinecolor );
    _gridlinepen.setStyle( Qt::SolidLine /*Qt::DotLine*/ );
    _gridlinepen.setWidth(1);

    _gridlinetextpen.setColor( "#555555" );
    _gridlinetextfont = QFont( "Arial", 7 );

    QColor gridspeciallinecolor( Qt::black );
    gridspeciallinecolor.setAlpha( 50 );
    _gridspeciallinepen.setColor( gridspeciallinecolor );
    _gridspeciallinepen.setStyle( Qt::SolidLine /*Qt::DashLine*/ );
    _gridspeciallinepen.setWidth(1);

    _framepen.setColor( "#555555" );
    _framepen.setStyle( Qt::SolidLine );
    _framepen.setWidth(1);

    _marcadorpen = QPen( "red" );
    _marcadorbrush = QBrush( "#FFCCCC" );

    _marcadormasprofundopen = QPen( "green" );
    _marcadormasprofundobrush = QBrush( "lightgreen" );
    _marcadormasprofundotextopen = QPen( "#555555" );
    _marcadortextopen = QPen( "#555555" );
    _marcadortextofont = QFont( "Arial", 7 );

    addGraphHeader( false );
    _tipo = Tipo::Profundidad;
    _vermapa = true;
    connect( &_mapdownloader, SIGNAL( finished( QNetworkReply* ) ), SLOT( mapDownloaded( QNetworkReply* ) ) );
}

void InmersionGrafico::setBuceador( Buceador* buceador )
{
    _buceador = buceador;
    getMap();
}

void InmersionGrafico::addGraphHeader( bool show )
{
    _verlayout = new QGridLayout();
    _graphtitle = new QLabel();
    _graphtitle->setFont( QFont( "Arial", 18 ) );
    _verProfundidadRadio = new QRadioButton( trUtf8( "Profundidad" ) );
    _verTemperaturaRadio = new QRadioButton( trUtf8( "Temperatura" ) );
    _verPresionRadio = new QRadioButton( trUtf8( "Presión" ) );
    _verTasaCasRadio = new QRadioButton( trUtf8( "Tasa CAS" ) );
    _verProfundidadRadio->setChecked( true );
    connect( _verProfundidadRadio, SIGNAL( clicked( bool ) ), this, SLOT( verProfundidad( bool ) ) );
    connect( _verTemperaturaRadio, SIGNAL( clicked( bool ) ), this, SLOT( verTemperatura( bool ) ) );
    connect( _verPresionRadio, SIGNAL( clicked( bool ) ), this, SLOT( verPresion( bool ) ) );
    connect( _verTasaCasRadio, SIGNAL( clicked( bool ) ), this, SLOT( verTasaCAS( bool ) ) );
    _verlayout->addWidget( _graphtitle, 0, 0, 1, 4, Qt::AlignCenter );
    _verlayout->addWidget( _verProfundidadRadio, 1, 0, 1, 1, Qt::AlignRight );
    _verlayout->addWidget( _verTemperaturaRadio, 1, 1, 1, 1 );
    _verlayout->addWidget( _verPresionRadio, 1, 2, 1, 1 );
    _verlayout->addWidget( _verTasaCasRadio, 1, 3, 1, 1 );
    _verlayout->setColumnStretch( 0, 1 );
    _verlayout->setColumnStretch( 3, 1 );
    _verlayout->setRowStretch( 2, 1 );
    setLayout( _verlayout );
    showGraphHeader( show );
}

void InmersionGrafico::verProfundidad( bool checked )
{
    if( checked )
    {
        if( _tipo != Tipo::Profundidad )
        {
            emit profundidadEnabled( true );
            _verProfundidadRadio->setChecked( true );
            _tipo = Tipo::Profundidad;
        }
        update();
    }
}

void InmersionGrafico::verTemperatura( bool checked )
{
    if( checked )
    {
        if( _tipo != Tipo::Temperatura )
        {
            emit temperaturaEnabled( true );
            _verTemperaturaRadio->setChecked( true );
            _tipo = Tipo::Temperatura;
        }
        update();
    }
}

void InmersionGrafico::verPresion( bool checked )
{
    if( checked )
    {
        if( _tipo != Tipo::Presion )
        {
            emit presionEnabled( true );
            _verPresionRadio->setChecked( true );
            _tipo = Tipo::Presion;
        }
        update();
    }
}

void InmersionGrafico::verTasaCAS( bool checked )
{
    if( checked )
    {
        if( _tipo != Tipo::TasaCAS )
        {
            emit tasacasEnabled( true );
            _verTasaCasRadio->setChecked( true );
            _tipo = Tipo::TasaCAS;
        }
        update();
    }
}

void InmersionGrafico::getMap()
{
    QString mapname( _buceador->usuario().toLower() + Constant::mapextension );
    if( QFile( mapname ).exists() )
    {
        QSettings settings;
        settings.beginGroup( _buceador->usuario() );
        if( settings.value( "mapurl" ).toString() == _buceador->mapUrl() )
        {
            _map = QPixmap( mapname );
            scaleMap();
            return;
        }
        qDebug() << "updating map";
    }
    else qDebug() << "map doesn't exist";
    qDebug() << "downloading map";
    _mapdownloader.get( QNetworkRequest( _buceador->mapUrl() ) );
}

void InmersionGrafico::mapDownloaded( QNetworkReply* reply )
{
    if( reply->error() ) qWarning() << "Unable to download map" << reply->errorString();
    else
    {
        QString mapname( _buceador->usuario().toLower() + Constant::mapextension );
        QFile file( mapname );
        if( file.exists() )
        {
            if( !file.remove() )
            {
                qWarning() << "Error deleting old map: Cannot save new map";
                return;
            }
        }
        if( !file.open( QIODevice::WriteOnly ) )
        {
            qWarning() << "Cannot save new map:" << file.errorString();
            return;
        }
        file.write( reply->readAll() );
        file.close();
        QSettings settings;
        settings.beginGroup( _buceador->usuario() );
        settings.setValue( "mapurl", _buceador->mapUrl() );
        _map = QPixmap( mapname );
    }
    reply->deleteLater();
    scaleMap();
    update();
}

void InmersionGrafico::resizeEvent( QResizeEvent* /*event*/ )
{
    if( _map.isNull() ) return;
    scaleMap();
}

void InmersionGrafico::scaleMap()
{
    qreal scaledwidth = 0.9 * width();
    qreal scaledheight = 0.9 * height();
    if( scaledwidth > MAP_MAXWIDTH ) scaledwidth = MAP_MAXWIDTH;
    if( scaledheight > MAP_MAXHEIGHT ) scaledheight = MAP_MAXHEIGHT;
    _scaledmap = _map.scaled( (scaledwidth-5), scaledheight, Qt::KeepAspectRatio, Qt::SmoothTransformation );
}

void InmersionGrafico::showGraphHeader( bool show, const QString& title )
{
    _graphtitle->setText( title );
    _graphtitle->setVisible( show );
    _verProfundidadRadio->setVisible( show );
    _verTemperaturaRadio->setVisible( show );
    _verPresionRadio->setVisible( show );
    _verTasaCasRadio->setVisible( show );
}

InmersionGrafico::Tipo InmersionGrafico::showGrafico( Inmersion* inmersion )
{
    _inmersion = inmersion;
    _vermapa = false;
    if( _inmersion )
        showGraphHeader( true, _inmersion->sitio()->nombre() );
    else showGraphHeader( false );
    update();
    return _tipo;
}

void InmersionGrafico::verMapa( bool show )
{
    if( _inmersion )
        showGraphHeader( !show, _inmersion->sitio()->nombre() );
    _vermapa = show;
    update();
}

void InmersionGrafico::drawMap()
{
    if( _map.isNull() ) return;
    QPainter painter( this );
    qreal wo = width() - _scaledmap.width();
    qreal ho = height() - _scaledmap.height();
    painter.drawPixmap( (wo/2)+5, (ho/2), _scaledmap );
    painter.setPen( _framepen );
    painter.drawRect( (wo/2)+5, (ho/2), _scaledmap.width(), _scaledmap.height() );
}

void InmersionGrafico::paintEvent( QPaintEvent* /*event*/ )
{
    if( _vermapa )
    {
        drawMap();
        return;
    }
    if( !_inmersion ) return;

    _muestras = _inmersion->muestras();

    _graphtopmargin = (_topmarginpct/100) * height(); // top margin of 10%
    _graphbottommargin = (_bottommarginpct/100) * height(); // bottom margin of 10%

    // drawarea and actual grapharea (which is drawarea without the topmargin and bottommargin
    _drawarea = QRectF(
        _drawareasidemargin, // left
        _drawareatopmargin, // top
        (width()-(2*_drawareasidemargin)), // width
        (height()-(_drawareatopmargin+_drawareabottommargin)) // height
    );
    _grapharea = QRectF(
        _drawarea.left() + _borderwidth,
        _drawarea.top() + _graphtopmargin,
        _drawarea.width() - _borderwidth,
        _drawarea.height() - (_graphtopmargin+_graphbottommargin)
    );

    _widthfactor = _grapharea.width() / (qreal) _inmersion->maxTiempo();
    switch( _tipo )
    {
        case Tipo::Profundidad:
            _heightfactor = _grapharea.height() / (qreal) _inmersion->profundidadMaxima();
            _gridheight = (Default::meterspergridline*_heightfactor);
            _gridwidth = (Default::secondspergridline*_widthfactor);
            if( _muestras.count() > 0 )
                paintProfundidad();
            else paintSimpleProfundidad();
            break;
        case Tipo::Temperatura:
            _heightfactor = _grapharea.height() / (qreal) Default::degreesrange;
            _gridheight = (Default::degreespergridline*_heightfactor);
            _gridwidth = (Default::secondspergridline*_widthfactor);
            if( _muestras.count() > 0 )
                paintTemperatura();
            else paintSimpleTemperatura();
            break;
        case Tipo::Presion:
            paintPresion();
            break;
        case Tipo::TasaCAS:
            paintTasaCAS();
            break;
    }
}

void InmersionGrafico::paintTemperatura()
{
    QPainter painter( this );
    Muestra* muestra = _muestras.first();
    QPainterPath path;
    bool started = false;
    quint32 temperatura = 0;
    quint32 tempmasalta = 0;
    quint32 tempmasbaja = 0;
    for( int i = 0; i < _muestras.size(); ++i )
    {
        muestra = _muestras.at(i);
        if( muestra->marcador() != Muestra::NoMarcador ) continue;
        temperatura = muestra->temperatura();
        if( temperatura == 0 ) continue;
        if( temperatura > tempmasalta ) tempmasalta = temperatura;
        if( temperatura < tempmasbaja ) tempmasbaja = temperatura;
        if( started )
            path.lineTo( _grapharea.left() + ( (qreal) muestra->tiempo() * _widthfactor ),
                         _grapharea.bottom() - ( (qreal) temperatura * _heightfactor ) );
        else
        {
            path.moveTo( _grapharea.left(),
                         _grapharea.bottom() - ( (qreal) muestra->temperatura() * _heightfactor ) );
            started = true;
        }
    }
    path.lineTo( _grapharea.right(), path.currentPosition().y() );

    QLinearGradient gradient( _grapharea.topLeft(), _grapharea.bottomLeft() );
    gradient.setColorAt( 0, "darkred" );
    gradient.setColorAt( 0.5, "#FFCCCC" );
    gradient.setColorAt( 1, "lightsteelblue" );
    _drawareabrush = QBrush( gradient );

    if( !( tempmasalta == 0 && tempmasbaja == 0 ) )
    {
        //drawGraphLine( &painter, &path );
        drawGraphArea( &painter, &path );
    }
    drawTemperaturaGridLines( &painter );
    drawTiempoGridLines( &painter );
    drawGraphFrame( &painter );
}

void InmersionGrafico::paintSimpleTemperatura()
{
    QPainter painter( this );
    qreal toptemp = 0;
    qreal bottomtemp = 0;
    if( !_inmersion->temperaturaSuperficie().isNull() || !_inmersion->temperaturaFondo().isNull() )
    {
        if( _inmersion->temperaturaSuperficie().isNull() )
        {
            toptemp = (qreal) _inmersion->temperaturaFondo().value();
            bottomtemp = toptemp;
        }
        else
        {
            toptemp = (qreal) _inmersion->temperaturaSuperficie().value();
            if( _inmersion->temperaturaFondo().isNull() )
                bottomtemp = toptemp;
            else bottomtemp = _inmersion->temperaturaFondo().value();
        }
        QPainterPath path( QPointF( _grapharea.left(), _grapharea.bottom() - (toptemp*_heightfactor) ) );
        path.lineTo( _grapharea.left() + (0.1*_grapharea.width()), _grapharea.bottom() - ((qreal)toptemp*_heightfactor) );
        path.lineTo( _grapharea.left() + (0.2*_grapharea.width()), _grapharea.bottom() - ((qreal)bottomtemp*_heightfactor) );
        path.lineTo( _grapharea.left() + (0.8*_grapharea.width()), _grapharea.bottom() - ((qreal)bottomtemp*_heightfactor) );
        path.lineTo( _grapharea.left() + (0.9*_grapharea.width()), _grapharea.bottom() - ((qreal)toptemp*_heightfactor) );
        path.lineTo( _grapharea.right(), _grapharea.bottom() - ((qreal)toptemp*_heightfactor) );

        QLinearGradient gradient( _grapharea.topLeft(), _grapharea.bottomLeft() );
        gradient.setColorAt( 0, "darkred" );
        gradient.setColorAt( 0.5, "#FFCCCC" );
        gradient.setColorAt( 1, "lightsteelblue" );
        _drawareabrush = QBrush( gradient );

        //drawGraphLine( &painter, &path );
        drawGraphArea( &painter, &path );
    }
    drawTemperaturaGridLines( &painter );
    drawTiempoGridLines( &painter );
    drawGraphFrame( &painter );
}

void InmersionGrafico::paintProfundidad()
{
    QPainter painter( this );

    QPainterPath path( _grapharea.topLeft() );

    Muestra* muestra = NULL;
    QPointF punto;
    Muestra* muestramasprofunda = NULL;
    QPointF puntomuestramasprofunda;
    _marcadores.clear();
    for( int i = 0; i < _muestras.size(); ++i )
    {
        muestra = _muestras.at(i);
        punto = QPointF( _grapharea.left() + ((qreal)muestra->tiempo()*_widthfactor),
                         _grapharea.top() + ((qreal)muestra->profundidad()*_heightfactor) );
        if( muestra->marcador() == Muestra::NoMarcador )
        {
            path.lineTo( punto );
            if( punto.y() > _grapharea.bottom() ) _grapharea.setBottom( punto.y() );
            if( !muestramasprofunda || (muestra->profundidad()>muestramasprofunda->profundidad()) )
            {
                muestramasprofunda = muestra;
                puntomuestramasprofunda = path.currentPosition();
            }
        }
        else _marcadores.insert( punto, muestra );
    }
    path.lineTo( _grapharea.topRight() ); // end path at top right

    puntomuestramasprofunda.setY( _grapharea.bottom() - 1 );

    _linepen.setColor( "steelblue" );
    _drawareabrush = QBrush( "lightsteelblue" );

    drawGraphLine( &painter, &path );
    drawGraphArea( &painter, &path );
    drawSuperficieLine( &painter );
    drawFondoLine( &painter );
    drawProfundidadGridLines( &painter );
    drawTiempoGridLines( &painter );
    drawPuntoMasProfundo( &painter, puntomuestramasprofunda, muestramasprofunda );
    drawMarcadores( &painter );
    drawGraphFrame( &painter );
}

void InmersionGrafico::paintSimpleProfundidad()
{
    QPainter painter( this );

    QPainterPath path( _grapharea.topLeft() );

    qreal graphleft = _grapharea.left();
    qreal graphbottom = _grapharea.bottom() - 1;
    quint32 maxtiempo = _inmersion->maxTiempo();
    qreal graphtop = _grapharea.top();

    // only create a graph with safetystop if the inmersion was longer than 600s
    if( maxtiempo > 600 )
    {
        qreal safetystopy = graphtop + (5*_heightfactor) + 1;
        //path.lineTo( graphleft+(60*_widthfactor), graphtop );
        path.lineTo( graphleft+(180*_widthfactor), graphbottom );
        path.lineTo( graphleft+((maxtiempo-480)*_widthfactor), graphbottom );
        path.lineTo( graphleft+((maxtiempo-360)*_widthfactor), safetystopy );
        path.lineTo( graphleft+((maxtiempo-60)*_widthfactor), safetystopy );
    }
    else // create a simple graph
    {
        qreal graphwidth = _grapharea.width();
        path.lineTo( graphleft+(0.1*graphwidth), graphtop );
        path.lineTo( graphleft+(0.2*graphwidth), graphbottom );
        path.lineTo( graphleft+(0.8*graphwidth), graphbottom );
        path.lineTo( graphleft+(0.9*graphwidth), graphtop );
    }
    path.lineTo( _grapharea.topRight() );

    _linepen.setColor( "steelblue" );
    _drawareabrush = QBrush( "lightsteelblue" );

    drawGraphLine( &painter, &path );
    drawGraphArea( &painter, &path );
    drawProfundidadGridLines( &painter );
    drawTiempoGridLines( &painter );
    drawGraphFrame( &painter );
}

void InmersionGrafico::paintPresion()
{

}

void InmersionGrafico::paintTasaCAS()
{

}

void InmersionGrafico::drawMarcadores( QPainter* painter )
{
    QList<QPointF> puntos = _marcadores.uniqueKeys();
    foreach( const QPointF punto, puntos )
    {
        QList<Muestra*> muestras = _marcadores.values( punto );
        QStringList muestratexts;
        foreach( Muestra* muestra, muestras )
        {
            quint32 tiempo = muestra->tiempo();
            // superficie marcadores are almost never useful
            switch( muestra->marcador() )
            {
                case Muestra::Superficie:
                    // obviously, you start and end at superficie
                    if( tiempo == 0 || tiempo == _inmersion->maxTiempo() ) { /*muestratexts << Marcador::superficie;*/ }
                    // filter out the ones close to the beginning or end
                    else if( tiempo < 180 || tiempo > (_inmersion->maxTiempo()-180) ) { /*muestratexts << Marcador::superficie;*/ }
                    // we only draw actual marcadores for superficie
                    else muestratexts << Marcador::superficie;
                    break;
                case Muestra::AvisoAscenso:
                    muestratexts << Marcador::avisoascenso;
                    break;
                case Muestra::AvisoRgbm:
                    // ignore avisorgbm at start
                    if( tiempo == 0 ) { /*muestratexts << Marcador::avisorgbm;*/ }
                    else muestratexts << Marcador::avisorgbm;
                    break;
                case Muestra::ErrorTechoPso:
                    muestratexts << Marcador::errortechopso;
                    break;
                case Muestra::ParadaSeguridadObligatoria:
                    muestratexts << Marcador::pso;
                    break;
                case Muestra::Personal:
                    //muestratexts << "Marcador personal";
                    break;
            }
        }
        if( muestratexts.size() > 0 )
        {
            painter->setRenderHint( QPainter::Antialiasing );
            painter->setPen( _marcadorpen );
            painter->setBrush( _marcadorbrush );
            painter->drawEllipse( QRect( punto.x()-(_marcadorsize/2), punto.y()-(_marcadorsize/2), _marcadorsize, _marcadorsize ) );
            painter->setPen( _marcadortextopen );
            painter->setFont( _marcadortextofont );
            quint32 textwidth = 250;
            quint32 textheight = muestratexts.count() * 15;
            painter->drawText( QRectF( (punto.x()-textwidth-_textmargin), (punto.y()-textheight-_textmargin), textwidth, textheight ),
                               Qt::AlignRight | Qt::AlignBottom,
                               muestratexts.join( "\n" ) );
        }
    }
}

void InmersionGrafico::drawPuntoMasProfundo( QPainter* painter, const QPointF& punto, Muestra* muestra )
{
    painter->setRenderHint( QPainter::Antialiasing );
    painter->setPen( _marcadormasprofundopen );
    painter->setBrush( _marcadormasprofundobrush );
    painter->drawEllipse( QRect( punto.x()-(_marcadorsize/2), punto.y()-(_marcadorsize/2), _marcadorsize, _marcadorsize ) );
    qreal textareawidth = 100;
    qreal textareaheight = 30;
    if( punto.y()+_textmargin+textareaheight < _drawarea.bottom() )
    {
        painter->setPen( _marcadortextopen );
        painter->setFont( _marcadortextofont );
        qreal textarealeft = punto.x()+_textmargin;
        int textareaalignment = Qt::AlignLeft | Qt::AlignTop;
        if( (punto.x()+_textmargin+textareawidth) > _drawarea.right() && (_drawarea.left()+textareawidth+_textmargin) < punto.x() )
        {
            textarealeft = punto.x() - textareawidth - _textmargin;
            textareaalignment = Qt::AlignRight | Qt::AlignTop;
        }
        painter->setPen( _marcadormasprofundotextopen );
        painter->drawText( QRectF( textarealeft, punto.y()+_textmargin, textareawidth, textareaheight ),
                           textareaalignment,
                           trUtf8( "Tiempo: %1%2%3%4\n"
                                   "Profundidad: %L5%6" )
                           .arg( muestra->tiempo()/SEGUNDOS_EN_MINUTO ).arg( Unidad::minutoscomilla )
                           .arg( (muestra->tiempo()%SEGUNDOS_EN_MINUTO), 2, 10, QChar('0') ).arg( Unidad::segundoscomillas )
                           .arg( _inmersion->profundidadMaxima() ).arg( Unidad::profundidad ) );
    }
}

void InmersionGrafico::drawGraphArea( QPainter* painter, QPainterPath* path )
{
    // close the path to get the graph area
    QPainterPath fill( *path );
    fill.lineTo( _drawarea.bottomRight() );
    fill.lineTo( _drawarea.bottomLeft() );
    path->closeSubpath();

    painter->setRenderHint( QPainter::Antialiasing );
    painter->setBrush( _drawareabrush );
    painter->setPen( Qt::NoPen );
    painter->drawPath( fill );
}

void InmersionGrafico::drawGraphLine( QPainter* painter, QPainterPath* path )
{
    painter->setPen( _linepen );
    painter->setRenderHint( QPainter::Antialiasing );
    painter->drawPath( *path );
}

void InmersionGrafico::drawSuperficieLine( QPainter* painter, bool includetext )
{
    painter->setRenderHint( QPainter::Antialiasing, false );
    painter->setFont( _gridlinetextfont );
    painter->setPen( _gridspeciallinepen );
    painter->drawLine( QLineF( _grapharea.topLeft(), _grapharea.topRight() ).translated(0,-1) );
    if( includetext )
    {
        painter->setPen( _gridlinetextpen );
        painter->drawStaticText( (_grapharea.left()+_textmargin), (_grapharea.top()-15), Strings::superficie );
    }
}

void InmersionGrafico::drawFondoLine( QPainter* painter, bool includetext )
{
    painter->setRenderHint( QPainter::Antialiasing, false );
    painter->setFont( _gridlinetextfont );
    painter->setPen( _gridspeciallinepen );
    painter->drawLine( QLineF( _grapharea.bottomLeft(), _grapharea.bottomRight() ).translated(0,-1) );
    if( includetext )
    {
        painter->setPen( _gridlinetextpen );
        painter->drawText( QRect( _textmargin, _grapharea.bottom()-(0.5*_gridheight), _grapharea.left()-(2*_textmargin), _gridheight ),
                           trUtf8( "%L1%2" ).arg( _inmersion->profundidadMaxima() ).arg( Unidad::profundidad ),
                           QTextOption( Qt::AlignRight | Qt::AlignVCenter ) );
    }
}

void InmersionGrafico::drawProfundidadGridLines( QPainter* painter )
{
    painter->setRenderHint( QPainter::Antialiasing, false );
    painter->setFont( _gridlinetextfont );
    quint32 linenr = 1;
    qreal gridy = _grapharea.top() + _gridheight;
    while( gridy < _grapharea.bottom() )
    {
        painter->setPen( _gridlinepen );
        painter->drawLine( _grapharea.left(), gridy, _grapharea.right(), gridy );
        if( gridy+(2*_textmargin) < _grapharea.bottom() )
        {
            painter->setPen( _gridlinetextpen );
            painter->drawText( QRect( _textmargin, gridy-(0.5*_gridheight), _grapharea.left()-(2*_textmargin), _gridheight ),
                               trUtf8( "%L1%2" ).arg( linenr * Default::meterspergridline ).arg( Unidad::profundidad ),
                               QTextOption( Qt::AlignRight | Qt::AlignVCenter ) );
        }
        linenr++;
        gridy = _grapharea.top() + (linenr*_gridheight);
    }
}

void InmersionGrafico::drawTemperaturaGridLines( QPainter* painter )
{
    painter->setRenderHint( QPainter::Antialiasing, false );
    painter->setFont( _gridlinetextfont );
    quint32 linenr = 0;
    qreal gridy = _grapharea.bottom();
    while( gridy >= _grapharea.top() )
    {
        painter->setPen( _gridlinepen );
        painter->drawLine( _grapharea.left(), gridy, _grapharea.right(), gridy );
        painter->setPen( _gridlinetextpen );
        painter->drawText( QRect( _textmargin, gridy-(0.5*_gridheight), _grapharea.left()-(2*_textmargin), _gridheight ),
                           trUtf8( "%L1%2" ).arg( linenr * Default::degreespergridline ).arg( Unidad::temperatura ),
                           QTextOption( Qt::AlignRight | Qt::AlignVCenter ) );
        linenr++;
        gridy = _grapharea.bottom() - (linenr*_gridheight);
    }
}

void InmersionGrafico::drawTiempoGridLines( QPainter* painter )
{
    painter->setRenderHint( QPainter::Antialiasing, false );
    painter->setFont( _gridlinetextfont );
    quint32 linenr = 1;
    qreal gridx = (_grapharea.left()+_gridwidth);
    while( gridx < _grapharea.right() )
    {
        painter->setPen( _gridlinepen );
        painter->drawLine( gridx, _drawarea.top(), gridx, _drawarea.bottom() );
        if( gridx+(2*_textmargin) < _grapharea.right() )
        {
            painter->setPen( _gridlinetextpen );
            painter->drawText( QRectF( gridx-(0.5*_gridwidth), _drawarea.bottom()+_textmargin, _gridwidth, _drawareabottommargin-(2*_textmargin) ),
                               trUtf8( "%L1%2" ).arg( linenr * (Default::secondspergridline/SEGUNDOS_EN_MINUTO) ).arg( Unidad::minutoscomilla ),
                               QTextOption( Qt::AlignHCenter | Qt::AlignTop ) );
        }
        linenr++;
        gridx += _gridwidth;
    }
    painter->setPen( _gridlinetextpen );
    painter->drawText( QRectF( _drawarea.right(), _drawarea.bottom()+_textmargin, (_drawareasidemargin-_textmargin), _drawareabottommargin-(2*_textmargin) ),
                       QString( "%1%2%3%4" ).arg( _inmersion->duracion()/SEGUNDOS_EN_MINUTO ).arg( Unidad::minutoscomilla )
                                            .arg( (_inmersion->duracion()%SEGUNDOS_EN_MINUTO), 2, 10, QChar('0') ).arg( Unidad::segundoscomillas ),
                       QTextOption( Qt::AlignLeft | Qt::AlignTop ) );
}

void InmersionGrafico::drawGraphFrame( QPainter* painter )
{
    painter->setRenderHint( QPainter::Antialiasing, false );
    painter->setPen( _framepen );
    painter->setBrush( Qt::NoBrush );
    painter->drawRect( _drawarea );
}
